<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2019/5/6
 * Time: 9:27
 */

namespace app\api\controller\user;

use app\admin\model\WarehouseGeneralSku;
use app\api\controller\HomeCommon;
use app\api\controller\Money\Money;
use app\api\controller\product\Product;
use app\api\model\Config;
use app\api\model\Log;
use app\api\model\ProductCart;
use app\api\model\ProductOrderDetail;
use app\api\model\ProductOrderDetailReturn;
use app\api\model\ProductOrderRelation;
use app\api\model\ProductOrderReturn;
use app\api\model\Shop;
use app\common\model\ProductOrderSpell;
use app\common\model\ProductOut;
use app\common\model\ProductSpell;
use app\lib\exception\FailedException;
use app\lib\exception\NotFoundException;
use app\lib\exception\ParameterException;
use app\Validate\AddressIdValidate;
use app\Validate\ExpressValidate;
use app\Validate\IdArrayMustPositive;
use app\Validate\IdMustPositive;
use app\Validate\PageMustValidate;
use app\Validate\ReturnValidate;
use app\Validate\SourceValidate;
use app\Validate\UserCartAddValidate;
use Payment\Client\Charge;
use Payment\Common\PayException;
use think\Db;
use think\Request;


class ProductOrder extends HomeCommon
{
    /**
     * 从购物车点结算过来的页面
     * @param Request $request
     * @param int $returnType
     * @return \think\response\Json
     * @throws FailedException
     * @throws NotFoundException
     * @throws ParameterException
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function settlementByCart(Request $request,$returnType=1){
        (new IdArrayMustPositive())->goCheck();
        (new AddressIdValidate())->goCheck();
        $post = $request->post();
        $cartList = (new ProductCart())->getCart($post);
        $result = (new ProductCart())->checkCart($cartList,$post["user_id"]);
        if($result['code']!=1){
            throw new FailedException(['msg'=>$result['msg']]);
        }
        $cartList = $result['cartList'];
        $cartList  = (new ProductCart())->getShopProduct($cartList);
        $rule = (new Config())->getConfigKey();
        $data  = (new ProductCart())->getFreightByAddress($post['user_id'],$post['address_id'],$post['getType'],$rule,$cartList);

        if($returnType==1){
            unset($data['user_address']);
            return writeJson(200,$data);
        }else{
            return $data;
        }
    }

    /**
     * 点击立即结算
     * @param Request $request
     * @param int $returnType
     * @return \think\response\Json
     * @throws FailedException
     * @throws NotFoundException
     * @throws ParameterException
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function settlementRightNow(Request $request,$returnType=1){
        (new UserCartAddValidate())->goCheck();
        (new AddressIdValidate())->goCheck();
        $post = $request->post();
        $check = (new \app\api\model\Product())->check_data($post['product_id']);
        if($check['code']!=1){
            throw new FailedException(['msg'=>$check['msg']]);
        }
        foreach ($post['skuList'] as &$value){
            $value['update_time'] = time();
            $value['product_id'] =$post['product_id'];
            $value['product_name'] = $check['list']['product_name'];
            $value['unit_number'] = $check['list']['unit_number'];
            $value['fcl_weight'] = $check['list']['fcl_weight'];
            $value['fcl_volume'] = $check['list']['fcl_volume'];
            $value['one_weight'] = $check['list']['one_weight'];
            $value['cover_img'] = $check['list']['cover_img'];
            $value['unit'] = $check['list']['unit'];
            $value['type'] = $check['shop']['type'];
            $value['name'] = $check['shop']['name'];
            $value['uid'] = $check['shop']['id'];
            $value['sku_remark'] = $check['list']['sku_remark'];
        }
        $result = (new ProductCart())->checkCart($post['skuList'],$post["user_id"]);
        if($result['code']!=1){
            throw new FailedException(['msg'=>$result['msg']]);
        }
        $cartList = $result['cartList'];
        $cartList  = (new ProductCart())->getShopProduct($cartList);
        $rule = (new Config())->getConfigKey();
        $data = (new ProductCart())->getFreightByAddress($post['user_id'],$post['address_id'],$post['getType'],$rule,$cartList);
        if($returnType==1){
            unset($data['user_address']);
            return writeJson(200,$data);
        }else{
            return $data;
        }
    }

    /**
     * 清仓商品点击立即结算
     * @param Request $request
     * @param int $returnType
     * @return array|\think\response\Json
     * @throws FailedException
     * @throws NotFoundException
     * @throws ParameterException
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function settlementOut(Request $request,$returnType=1){
        (new UserCartAddValidate())->goCheck();
        (new AddressIdValidate())->goCheck();
        $post = $request->post();

        //获取当前清仓商品信息
        $productOutService = new ProductOut();
        $ourModel = $productOutService->where(["id"=>$post["out_id"]])->find();
        if($ourModel == null){ throw new FailedException(['msg'=>"当前清仓商品不存在"]);}
        if($post['skuList'][0]["number"] < $ourModel["batch_num"]){ throw new FailedException(['msg'=>"不满足起批数量"]);}

        //判断商家是否存在
        $check = (new \app\api\model\Product())->check_data($post['product_id']);
        if($check['code']!=1){ throw new FailedException(['msg'=>$check['msg']]); }

        //商品信息赋值
        foreach ($post['skuList'] as &$value){
            $value['update_time'] = time();
            $value['product_id'] =$post['product_id'];
            $value['product_name'] = $check['list']['product_name'];
            $value['unit_number'] = $check['list']['unit_number'];
            $value['fcl_weight'] = $check['list']['fcl_weight'];
            $value['fcl_volume'] = $check['list']['fcl_volume'];
            $value['one_weight'] = $check['list']['one_weight'];
            $value['cover_img'] = $check['list']['cover_img'];
            $value['unit'] = $check['list']['unit'];
            $value['type'] = $check['shop']['type'];
            $value['name'] = $check['shop']['name'];
            $value['uid'] = $check['shop']['id'];
            $value['sku_remark'] = $check['list']['sku_remark'];
        }

        //判断当前商品库存是否充足
        $warehouseGeneralSkuService = new WarehouseGeneralSku();
        $model = $warehouseGeneralSkuService->where(["id"=>$ourModel["general_sku_id"]])->find();
        if($model == null){ throw new FailedException(['msg'=>'库存不足']);}
        if(($model["stock"] - $post['skuList'][0]["number"]) < 0){ throw new FailedException(['msg'=>'库存不足']);}

        //赋值价格
        $post['skuList'][0]["price"] = $ourModel["out_price"];

        //初始化自提地址
        $cartList[0] = [
            'productList'=>[],
            'type'=>3,
            'sort'=>0,
            'shop_name'=>"万享集",
            'pick_address'=>"万享集仅限包邮",//自提地址
            'uid' =>'0',
            'name' =>"万享集",
            'update_time'=>time(),

        ];
        $config_model = (new \app\admin\controller\config\Config())->getToTheAddress(1);
        $cartList[0]['pick_address'] = $config_model['address'];
        $cartList[0]["productList"] = $post['skuList'];
        $cartList[0]["order_type_id"] = $post['out_id'];

        $rule = (new Config())->getConfigKey();
        $data = (new ProductCart())->getFreightByAddress($post['user_id'],$post['address_id'],$post['getType'],$rule,$cartList);
        if($returnType==1){
            unset($data['user_address']);
            return writeJson(200,$data);
        }else{
            return $data;
        }
    }

    /**
     * 拼团点击立即结算
     * @param Request $request
     * @param int $returnType
     * @return array|\think\response\Json
     * @throws FailedException
     * @throws NotFoundException
     * @throws ParameterException
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function settlementSpell(Request $request,$returnType=1){
        (new UserCartAddValidate())->goCheck();
        (new AddressIdValidate())->goCheck();
        $post = $request->post();

        //获取当前拼团商品信息
        $productSpellService = new ProductSpell();
        $spellModel = $productSpellService->where(["id"=>$post["spell_id"]])->find();
        if($spellModel == null){ throw new FailedException(['msg'=>"当前拼团商品不存在"]);}
        if($post['skuList'][0]["number"] != $spellModel["batch_num"]){ throw new FailedException(['msg'=>"不满足起批数量"]);}

        //检查当前参与团是否已经参与
        $productOrderSpellService = new ProductOrderSpell();
        if(isset($post['spell_parent_id'])){
            //查询当前团是否已经是团长
            $count1 = $productOrderSpellService
                ->where("id","eq",$post['spell_parent_id'])
                ->where("user_id","eq",$post['user_id'])
                ->whereNull("delete_time")
                ->count();

            //查询当前团是否已参与
            $count2 = $productOrderSpellService
                ->where("product_spell_id","eq",$post['spell_parent_id'])
                ->where("user_id","eq",$post['user_id'])
                ->whereNull("delete_time")
                ->count();
            if($count1 > 0 || $count2 > 0){
                throw new FailedException(['msg'=>"该拼团您已参与"]);
            }
        }

        //判断商家是否存在
        $check = (new \app\api\model\Product())->check_data($post['product_id']);
        if($check['code']!=1){ throw new FailedException(['msg'=>$check['msg']]); }

        //商品信息赋值
        foreach ($post['skuList'] as &$value){
            $value['update_time'] = time();
            $value['product_id'] =$post['product_id'];
            $value['product_name'] = $check['list']['product_name'];
            $value['unit_number'] = $check['list']['unit_number'];
            $value['fcl_weight'] = $check['list']['fcl_weight'];
            $value['fcl_volume'] = $check['list']['fcl_volume'];
            $value['one_weight'] = $check['list']['one_weight'];
            $value['cover_img'] = $check['list']['cover_img'];
            $value['unit'] = $check['list']['unit'];
            $value['type'] = $check['shop']['type'];
            $value['name'] = $check['shop']['name'];
            $value['uid'] = $check['shop']['id'];
            $value['sku_remark'] = $check['list']['sku_remark'];
        }

        //判断当前商品库存是否充足
        $warehouseGeneralSkuService = new WarehouseGeneralSku();
        $where[] = ["product_id","eq",$spellModel["product_id"]];
        $where[] = ["stock",">",$spellModel["batch_num"]];
        $where[] = ["stock",">",0];
        $model = $warehouseGeneralSkuService->where($where)->find();
        if($model == null){ throw new FailedException(['msg'=>'库存不足']);}

        //赋值价格
        $post['skuList'][0]["price"] = $spellModel["spell_price"];

        //初始化自提地址
        $cartList[0] = [
            'productList'=>[],
            'type'=>3,
            'sort'=>0,
            'shop_name'=>"万享集",
            'pick_address'=>"万享集仅限包邮",//自提地址
            'uid' =>'0',
            'name' =>"万享集",
            'update_time'=>time()
        ];
        $config_model = (new \app\admin\controller\config\Config())->getToTheAddress(1);
        $cartList[0]['pick_address'] = $config_model['address'];
        $cartList[0]["productList"] = $post['skuList'];
        $cartList[0]["order_type_id"] = $post['spell_id'];
        $cartList[0]["spell_parent_id"] = isset($post['spell_parent_id']) ? $post['spell_parent_id'] : 0;

        $rule = (new Config())->getConfigKey();
        $data = (new ProductCart())->getFreightByAddress($post['user_id'],$post['address_id'],$post['getType'],$rule,$cartList);
        if($returnType==1){
            unset($data['user_address']);
            return writeJson(200,$data);
        }else{
            return $data;
        }
    }

    /**
     * 用户创建订单
     * @param Request $request
     * @return \think\response\Json
     * @throws FailedException
     * @throws NotFoundException
     * @throws ParameterException
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function userCreateOrder(Request $request){
        (new AddressIdValidate())->goCheck();
        $post = $request->post();
        if(!isset($post['type'])){
            throw new ParameterException(['msg'=>'缺少提交类型']);//1是购物车 2是普通订单立即购买 3是清仓立即购买 4是拼团立即购买
        }
        if(!isset($post['source'])){
            throw new ParameterException(['msg'=>'缺少提交来源']);//1PC 2是 APP
        }
        if(!isset($post['pay_style'])){
            throw new ParameterException(['msg'=>'缺少支付类型']);//1是微信 2是支付宝 3是货到付款
        }
        if(!isset($post['getType'])){
            throw new ParameterException(['msg'=>'缺少送货类型']);//1是物流 2是自提
        }
        if($post['type']==1){
            $result = $this->settlementByCart($request,2);
        }else if($post['type']== 2){
            $result = $this->settlementRightNow($request,2);
        }else if($post['type']== 3){
            $result = $this->settlementOut($request,2);
        }else if($post['type']== 4){
            $result = $this->settlementSpell($request,2);
        }

        //生成总订单
        $order_relation = [
            'user_id'=>$post['user_id'],
            'pay_style'=>$post['pay_style'],
            'order_number'=>(new ProductOrderRelation())->createOrderNumber("POR"),
            'total_price'=>$result['total_price'],
            'total_number'=>$result['all_number'],
            'source'     =>$post['source']
        ];
        Db::startTrans();
        $relation_id = (new ProductOrderRelation())->dataUpdate($order_relation);
        if(!$relation_id){
            Db::rollback();
            throw new FailedException(['msg'=>'生成总订单失败']);
        }
        $number = 1;

        //如果是自提则有自提编号
        if($post['getType']==2) { //如果是自提 则有自提编号
            $day_number = (new \app\api\model\ProductOrder())->where([['day', 'eq', date("Ymd")]])->order("day_number desc")->find();
            if (!$day_number) {
                $number = 1;
            } else {
                $number = $day_number['day_number'] + 1;
            }
        }

        foreach ($result['cartList'] as $key=>$value){
            //修修补补，这里是默认自提地址产生的问题,需要过滤没有商品的单子
            if($value['productList'] == []){ continue; }

            //生成订单
            $order = [
                'shop_name' =>$value['shop_name'],
                'uid'    =>$value['uid']==0?-1:$value['uid'],  //如果uid为0则为交易大厅订单(赋特殊值为-1)
                'user_id'=>$post['user_id'],
                'pay_style'=>$post['pay_style'],
                'order_number'=>(new \app\api\model\ProductOrder())->createOrderNumber("PO"),
                'relation_id' =>$relation_id,
                'total_price'=>$result['total_price'],
                'total_number'=>$result['all_number'],
                'pay_money' =>$result['total_price'],
                'linkman'   =>!empty($result['user_address'])?$result['user_address']['linkman']:'',
                'contact_number'=>!empty($result['user_address'])?$result['user_address']['contact_number']:'',
                'address'    =>!empty($result['user_address'])?$result['user_address']['province'].$result['user_address']['city'].$result['user_address']['area'].$result['user_address']['address']:'',
                'freight'    =>$result['total_freight'],//运费
                'getType'    =>$post['getType'],//物流方式 1物流 2是自提
                'total_unit' =>$value['total_unit'],//总计算重量或者是体积
                'freight_type' =>$value['freight_type'],//运费方式 1是按重量 2是按体积
                'source'     =>$post['source'],
                'remark'     => "",
                'day'        =>date("Ymd")
            ];

            //赋值订单类型
            if ($post['type'] == 3) { //清仓订单
                $order["order_type"] = 2;
                $order["order_type_id"] = $value["order_type_id"];
            }
            else if ($post['type'] == 4){ //拼团订单
                $order["order_type"] = 3;
                $order["order_type_id"] = $value["order_type_id"];
            }
            else{
                $order["order_type"] = 1;
            }

            //赋值备注
            if(isset($post['remark'])){
                foreach ($post['remark'] as $k=>$v){
                    $order["remark"] = isset($v) ? $v : "";
                }
            }
            if($post['getType']==2){
                $order['day_number'] = $number;
                $number++;
            }
            $order_id = (new \app\api\model\ProductOrder())->dataUpdate($order);
            if(!$order_id){
                Db::rollback();
                throw new FailedException(['msg'=>'商家订单失败']);
            }

            //生成订单详情
            $new = [];
            foreach ($value['productList'] as $val){
                //订单详情
                $new[] = [
                    'uid'=>$val['uid'],
                    'order_id'=>$order_id,
                    'product_id'=>$val['product_id'],
                    'product_cover_img'=>$val['cover_img'],
                    'product_name' =>$val['product_name'],
                    'product_sku' => isset($val['sku_remark']) ? $val['sku_remark']: "",
                    'product_sku_name' => isset($val['sku_remark']) ? $val['sku_remark']: "",
                    'product_price' =>$val['price'],
                    'number' =>$val['number'],
                    'total_money'=>$val['number']*$val['price'],
                    'hall_id'=>isset($val['hall_id']) ? $val['hall_id'] : 0  //2019-9-17-Inke-新增位置字段，保存商品货位号ID
                ];

                //生成拼团
                if($post['type']== 4){
                    //额外增加一个参数
                    if(!isset($value["spell_parent_id"])){ throw new ParameterException(['msg'=>'缺少拼团参数']);}

                    //判断清仓商品是否存在在
                    $productSpellService = new ProductSpell();
                    $productSpellModel = $productSpellService->isExistsById($post["spell_id"]);
                    if($productSpellModel == null){ return writeJson(200,"当前清仓商品不存在","当前清仓商品不存在",10000);}

                    //判断当前父级团是否存在
                    $productOrderSpellService = new ProductOrderSpell();
                    $where[] = ["id","eq",$value["spell_parent_id"]];
                    $where[] = ["status","eq",1];
                    $spellModel = $productOrderSpellService->where($where)->find();

                    $newSpell = array(
                        "order_id"=>$order_id,
                        "user_id"=>$post['user_id'],
                        "product_id"=>$val['product_id'],
                        "product_spell_id"=>$value["order_type_id"],
                        "status"=>0,
                        "parent_id"=>isset($spellModel["id"]) ? $spellModel["id"] : 0,
                        "create_time"=>time(),
                    );

                    $res = $productOrderSpellService->save($newSpell);
                    if(!$res){
                        Db::rollback();
                        throw new FailedException(['msg'=>'拼团占位失败']);
                    }
                }
            }
            $res = (new ProductOrderDetail())->saveAll($new);
            if(!$res){
                Db::rollback();
                throw new FailedException(['msg'=>'订单详情添加失败']);
            }
        }

        //若是从购物车结算则清空购物车里所属商品
        if($post['type']==1){
            $post['id'] = array_values($post['id']);
            $where_cart = [
                ['id','in',$post['id']],
                ['user_id','eq',$post['user_id']]

            ];
            $res = (new ProductCart())->where($where_cart)->setField("delete_time",time());
            if(!$res){
                Db::rollback();
                throw new FailedException(['msg'=>"删除购物车失败"]);
            }
        }

        //若开启测试环境则价格为0.01
        if(TestPrice==1){
            $order_relation['total_price'] = 0.01;
        }

        //source1 为PC支付 2为APP支付
        if($post['source']==1){ //如果是PC端
            if($post['pay_style']==1){ //微信支付

                $orderInfo= [
                    'order_number'    => $order_relation['order_number'],
                    'total_price'    => $order_relation['total_price'],// 单位为元 ,最小为0.01
                    'order_type'     => 1
                ];
                $notify = "https://api.globaltc.cn/api/notify/wxNotify";
                $res = wxpay($orderInfo,$notify);
                Db::commit();
                return writeJson(200,['payInfo'=>$res,"order_id"=>$order_id,'order_number'=>$order_relation['order_number'],'total_price'=>$order_relation['total_price']]);
            }elseif($post['pay_style']==2){ //支付宝支付
                try {
                    $config = require_once  ALI_PATH."webaliconfig.php";
                    $info = [
                        'body'    => '网站支付',
                        'subject'    => '测试支付宝电脑网站支付',
                        'order_no'    => $order_relation['order_number'],
                        'timeout_express' => time() + 600,// 表示必须 600s 内付款
                        'amount'    => $order_relation['total_price'],// 单位为元 ,最小为0.01
                        'return_param' => '1_1',
                        'goods_type' => '0',// 0—虚拟类商品，1—实物类商品
                        'store_id' => '',
                        'qr_mod' => '',
                    ];
                    $res=  Charge::run("ali_web",$config,$info);
                    Db::commit();
                    return writeJson(200,['payInfo'=>$res,"order_id"=>$order_id]);
                } catch (PayException $e) {
                    Db::rollback();
                    throw new FailedException(['msg'=>$e->errorMessage()]);
                }
            }
        }elseif($post['source']==2){
            if($post['pay_style']==1){ //微信支付
                $config = require_once PAY_PATH . 'wxappconfig.php';
                $payData = [
                    'body'    => '万享集',
                    'subject'    => '万享集',
                    'order_no'    => $order_relation['order_number'],
                    'timeout_express' => time() + 600,// 表示必须 600s 内付款
                    'amount'    => $order_relation['total_price'],// 微信沙箱模式，需要金额固定为3.01
                    'return_param' => '2_1',
                    'client_ip' => isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '127.0.0.1',// 客户地址
                ];
                try {
                    $res=  Charge::run("wx_app",$config,$payData);

                    Db::commit();
                    return writeJson(200,['payInfo'=>$res,"order_id"=>$order_id]);
                } catch (PayException $e) {
                    Db::rollback();
                    throw new FailedException(['msg'=>$e->errorMessage()]);
                }
            }
            elseif($post['pay_style']==2){//支付宝支付
                try {
                    $config = require_once  ALI_PATH."aliconfig.php";
//                    $config['notify_url'] = $config['notify_url']."?source=2&&order_type=1"; //表示APP支付
                    $info = [
                        'body'=>'万享集',
                        'subject'=>'商城商品',
                        'order_no'=>$order_relation['order_number'],
                        'amount' =>$order_relation['total_price'],
                        'return_param' => '2_1',
                    ];
                    $res=  Charge::run("ali_app",$config,$info);
                    Db::commit();
                    return writeJson(200,['payInfo'=>$res,"order_id"=>$order_id]);
                } catch (PayException $e) {
                    Db::rollback();
                    throw new FailedException(['msg'=>$e->errorMessage()]);
                }
            }
            elseif ($post['pay_style']==3){
                //货到付款-将订单更改为待发货状态。
                $update = [
                    'pay_style'=>$post['pay_style'],
                    'status'=>1,
                ];
                $re = (new \app\api\model\ProductOrder())->where("id",$order_id)->update($update);
                if(!$re){
                    Db::rollback();
                    throw new FailedException(['msg'=>"添加订单失败"]);
                }
            }
            Db::commit();
            return writeJson(200,["order_id"=>$order_id]);
        }
    }

    /**
     * 用户支付小订单
     * @param Request $request
     * @return \think\response\Json
     * @throws ParameterException
     * @throws FailedException
     */
    public function userPayOrder(Request $request){
        (new IdMustPositive())->goCheck();
        (new SourceValidate())->goCheck();
        $post = $request->post();
        if(!isset($post['pay_style'])){
            throw new ParameterException(['msg'=>'缺少支付方式']);
        }
        $where = [
            ['id','eq',$post['id']],
            ['status','eq',0],
            ['user_id','eq',$post['user_id']]
        ];
        $order  = (new \app\api\model\ProductOrder())->findOne($where);
        if(!isset($order)){
            throw new FailedException(['msg'=>'用户订单不能支付']);
        }
        if(TestPrice==1){
            $order['total_price'] = 0.01;
        }
        if($post['source']==1){ //如果是PC端
            if($post['pay_style']==1){ //微信支付

                $orderInfo= [
                    'order_number'    => $order['order_number'],
                    'total_price'    => $order['total_price'],// 单位为元 ,最小为0.01
                    'order_type'     => 4 //4表示支付小订单
                ];
                $notify = "https://api.globaltc.cn/api/notify/wxNotify/order_type/1";
                $res = wxpay($orderInfo,$notify);
                Db::commit();
                return writeJson(200,['payInfo'=>$res,'order_number'=>$order['order_number'],'total_price'=>$order['total_price']]);
            }elseif($post['pay_style']==2){ //支付宝支付
                try {
                    $config = require_once  ALI_PATH."webaliconfig.php";
//                    $config['notify_url'] = $config['notify_url']."?source=1&&order_type=1";
                    $info = [
                        'body'    => '网站支付',
                        'subject'    => '测试支付宝电脑网站支付',
                        'order_no'    => $order['order_number'],
                        'timeout_express' => time() + 600,// 表示必须 600s 内付款
                        'amount'    => $order['total_price'],// 单位为元 ,最小为0.01
                        'return_param' => '1_4', //1表示PC支付 4表示 小订单支付
                        'goods_type' => '0',// 0—虚拟类商品，1—实物类商品
                        'store_id' => '',
                        'qr_mod' => '',
                    ];
                    $res=  Charge::run("ali_web",$config,$info);
//                    $res = urldecode($res);
                    Db::commit();
                    return writeJson(200,['payInfo'=>$res]);
                } catch (PayException $e) {
                    Db::rollback();
                    throw new FailedException(['msg'=>$e->errorMessage()]);
                }
            }
        }
        elseif($post['source']==2){
            if($post['pay_style']==1){ //微信支付
                $config = require_once PAY_PATH . 'wxappconfig.php';
                $payData = [
                    'body'    => '用户充值',
                    'subject'    => '用户充值',
                    'order_no'    => $order['order_number'],
                    'timeout_express' => time() + 600,// 表示必须 600s 内付款
                    'amount'    => $order['total_price'],// 微信沙箱模式，需要金额固定为3.01
                    'return_param' => '2_4',
                    'client_ip' => isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '127.0.0.1',// 客户地址
                ];
                try {
                    $res=  Charge::run("wx_app",$config,$payData);
                    Db::commit();
                    return writeJson(200,['payInfo'=>$res,'payData'=>$payData]);
                } catch (PayException $e) {
                    Db::rollback();
                    throw new FailedException(['msg'=>$e->errorMessage()]);
                }
            }elseif($post['pay_style']==2){//支付宝支付
                try {
                    $config = require_once  ALI_PATH."aliconfig.php";
//                    $config['notify_url'] = $config['notify_url']."?source=2&&order_type=1"; //表示APP支付
                    $info = [
                        'body'=>'万享集',
                        'subject'=>'商城商品',
                        'order_no'=>$order['order_number'],
                        'amount' =>$order['total_price'],
                        'return_param' => '2_4',
                    ];
                    $res=  Charge::run("ali_app",$config,$info);
                    Db::commit();
                    return writeJson(200,['payInfo'=>$res]);
                } catch (PayException $e) {
                    Db::rollback();
                    throw new FailedException(['msg'=>$e->errorMessage()]);
                }
            }
            Db::commit();
            return writeJson(200);
        }
    }

    /**
     * 用户订单列表
     * @param Request $request
     * @return \think\response\Json
     * @throws ParameterException
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function userOrderList(Request $request){
        (new PageMustValidate())->goCheck();
        $post = $request->post();
        $where = [['user_id','eq',$post['user_id']]];

        //订单状态
        if(isset($post['status']) && $post['status'] >= 0){
            $where = addWhere($post,['status'=>''],$where,1);
        }

        $where['page'] = $post['page'];
        $data = (new \app\api\model\ProductOrder())->wechatListTotalWith("order_detail,shop_type",$where,"*","id desc",$post['page_number']);
        foreach ($data["data"] as $k=>$v){
            //拼团订单
            if($v["order_type"] ==  3){
                //将团的情况查出来
                $data["data"][$k]["orderSpell"] = (new ProductOrderSpell())->getOrderSpell($v["id"]);
            }
        }
        return writeJson(200,$data);
    }

    /**
     * 用户取消订单
     * @param Request $request
     * @return \think\response\Json
     * @throws FailedException
     * @throws ParameterException
     */
    public function userCancelOrder(Request $request){
        (new IdMustPositive())->goCheck();
        $post = $request->post();
        if(!isset($post['content'])){
            throw new ParameterException(['msg'=>'请选择取消订单原因']);
        }
        $order = (new \app\api\model\ProductOrder())->findOne([['id','eq',$post['id']],['user_id','eq',$post['user_id']],['status','in',[0,1]]]);
        if(!$order){
            throw new FailedException(['msg'=>'订单不能取消']);
        }
        //订单取消分两种 一种是未支付取消 一种是待发货取消
        Db::startTrans();
        $new = [
            'id'=>$post['id'],
            'cancel_reason'=>$post['content'],
            'status' =>-1
        ];
        $res = (new \app\api\model\ProductOrder())->dataUpdate($new);
        if(!$res){
            Db::rollback();
            throw new FailedException(['msg'=>'订单取消失败']);
        }else{
            if($order['status']==1){
                //取消订单 原来返回 原路返回 子订单走子订单 总订单走总订单 通过 pay_from 1是总订单 2是子订单 去判断 //退款走退款的
                //根据订单的支付来源 退回到原来 微信PC支付 微信APP支付
                if($order['pay_form']==2){
                    $order_number = $order['order_number'];
                    $total_fee = $order['total_price'];
                } else{
                    $list = (new ProductOrderRelation())->findOne([['id','eq',$order['relation_id']]],"order_number,total_price");
                    $order_number = $list['order_number'];
                    $total_fee =$list['total_price'];
                }
                if(TestPrice==1){
                    $total_fee = 0.01;
                    $order['total_price'] = 0.01;
                }

                //如果是秒杀订单,则恢复库存
                if($order["order_type"] == 2){
                    $res = false;
                    if(!$res){
                        Db::rollback();
                        throw new FailedException(['msg'=>'取消秒杀操作失败']);
                    }
                }

                //如果是拼团订单,则团信息标记删除
                if($order["order_type"] == 3){
                    $res = (new ProductOrderSpell())->falseOrderSpell($order["id"]);
                    if(!$res){
                        Db::rollback();
                        throw new FailedException(['msg'=>'取消拼团操作失败']);
                    }
                }

                if($order['pay_style']==1){
                    $data = [
                        'out_trade_no' => $order_number,
                        'total_fee' => $total_fee,
                        'refund_fee' => $order['total_price'],
                        'refund_no' => "RE".time().rand(1000,9999),
                        'refund_account' => "",// REFUND_RECHARGE:可用余额退款  REFUND_UNSETTLED:未结算资金退款（默认）
                    ];
                    $res = wxreFund($data,$order['source']);
                    (new Log())->dataUpdate(['content'=>json_encode($res),'type'=>33]);
                    if(!isset($res['is_success'])||$res['is_success']!="T"){
                        Db::rollback();
                        throw new FailedException(['msg'=>'订单退款失败']);
                    }

                }elseif ($order['pay_style']==2){
                    $data = [
                        'out_trade_no' => $order_number,
                        'trade_no' => '',// 支付宝交易号， 与 out_trade_no 必须二选一
                        'refund_fee' => $order['total_price'],
                        'reason' => '我要退款',
                        'refund_no' => "RE".$order_number,
                    ];
                    $res = alireFund($data,$order['source']);
                    (new Log())->dataUpdate(['content'=>json_encode($res),'type'=>33]);
                    if(!isset($res['is_success'])||$res['is_success']!="T"){
                        Db::rollback();
                        throw new FailedException(['msg'=>'订单退款失败']);
                    }
                }
            }
            Db::commit();
            return writeJson(200,[],"订单取消成功");
        }
    }

    /**
     * 用户确认收货
     * @param Request $request
     * @return \think\response\Json
     * @throws FailedException
     * @throws ParameterException
     * @throws \think\Exception
     */
    public function userSureOrder(Request $request){
        (new IdMustPositive())->goCheck();
        $post = $request->post();
        $order = (new \app\api\model\ProductOrder())->findOne([['id','eq',$post['id']],['user_id','eq',$post['user_id']],['status','eq',2]]);
        if(!$order){
            throw new FailedException(['msg'=>'订单不能确认收货']);
        }
        Db::startTrans();
        $res = (new \app\api\model\ProductOrder())->where("id",$post['id'])->update(['status'=>4,'sure_time'=>time()]);//4是已完成
        if(!$res){
            Db::rollback();
            throw new FailedException(['msg'=>'操作失败']);
        }

        if($order['uid'] > 0){
            //将对应金额加入到商家的余额下面(大于零则有对应商家)
            $res = (new Shop())->where("id",$order['uid'])->setInc("money",$order['total_price']);
            if(!$res){
                Db::rollback();
                throw new FailedException(['msg'=>'商家加入余额失败']);
            }
            //处理商家等级
            $res = (new \app\api\model\ProductOrder())->shopLevel($order['uid'],$order['total_price']);
            if($res['code']!=1){
                Db::rollback();
                throw new FailedException(['msg'=>$res['msg']]);
            }
        }
        //处理订单 销量
        $res = (new \app\api\model\ProductOrder())->addSales($post['id']);
        if($res['code']!=1){
            Db::rollback();
            throw new FailedException(['msg'=>$res['msg']]);
        }
        //处理用户购次和 交易额
        $res = (new \app\admin\model\User())->where([['id','eq',$order['user_id']]])->setInc("buy_card_number");
        $res1 = (new \app\admin\model\User())->where([['id','eq',$order['user_id']]])->setInc("trade_money",$order['total_price']);
        if(!$res||!$res1){
            Db::rollback();
            throw new FailedException(['msg'=>'用户交易修改失败']);
        }

        //处理佣金
        (new \app\api\model\Money())->insertInviteRecord($post['id']);

        Db::commit();
        return writeJson(200,[],"操作成功");
    }

    /**
     * 用户评价订单
     * @param Request $request
     * @return \think\response\Json
     * @throws FailedException
     * @throws ParameterException
     */
    public function userReviewOrder(Request $request){
        (new IdMustPositive())->goCheck();
        (new SourceValidate())->goCheck();
        $post = $request->post();
        if(!isset($post['content'])){
            throw new ParameterException(['msg'=>'请输入评价内容']);
        }
        //处理订单评价状态
        $where =[
            ['id','eq',$post['id']],
            ['user_id','eq',$post['user_id']],
            ['status','eq',4],//状态为已完成
            ['is_review','eq',1]//评价状态为 未评价
        ];
        $order = (new \app\api\model\ProductOrder())->findOne($where);
        if(!$order){
            throw new FailedException(['msg'=>'订单不能评价']);
        }
        Db::startTrans();
        $res = (new \app\api\model\ProductOrder())->where("id",$post['id'])->setField("is_review",2);//2是已完成 1是未评价
        if(!$res){
            Db::rollback();
            throw new FailedException(['msg'=>'操作失败']);
        }
        $res = (new \app\api\model\ProductOrder())->orderReview($order['id'],$post['source'],$order["order_type"],$post['content'],$post['user_id']);

        if($res['code']!=1){
            Db::rollback();
            throw new FailedException(['msg'=>'操作失败']);
        }
        Db::commit();
        return writeJson(200,[],"评价成功");
    }

    /**
     * 用户申请售后
     * @param Request $request
     * @return \think\response\Json
     * @throws FailedException
     * @throws ParameterException
     */
    public function userApplyReturn(Request $request){
        //订单id
        (new IdMustPositive())->goCheck();
        (new ReturnValidate())->goCheck();
        $post = $request->post();
        $where = [
            ['id','eq',$post['id']], //订单id
            ['user_id','eq',$post['user_id']],//用户id
            ['status','eq',4],//订单状态
            ['return_status','eq',1]// 未申请过退款的
        ];
        $order = (new \app\api\model\ProductOrder())->findOne($where);
        if(!$order){
            throw new FailedException(['msg'=>'订单不能申请退款']);
        }
        if(time()>$order['sure_time']+7*86400){
            throw new FailedException(['msg'=>'订单超过7天不能退款']);
        }
        $where = [
            ['order_id','eq',$post['id']], //订单id
        ];
        $detail = (new ProductOrderDetail())->selectList($where);
        $detail = $detail->toArray();
        $detail = changeArrayKey($detail,"product_id");
        $new = [
            'user_id'=>$post['user_id'],
            'uid'    =>$order['uid'],
            'relation_id'=>$post['id'],
            'total_price' =>0,
            'order_number' =>(new ProductOrderReturn())->createOrderNumber("POR"),
            'total_number'  => 0,
            'return_remark' =>$post['return_remark'],
            'shop_name'     =>$order['shop_name']
        ];
        $newDetail = [];

        foreach ($post['detailList'] as $value){
            if(!isset($detail[$value['id']])){
                throw new FailedException(['msg'=>'退款选中的商品不存在']);
            }
            if($value['number']>$detail[$value['id']]['number']){
                throw new FailedException(['msg'=>'您选择退款的数量大于订单数量不能申请退款']);
            }
            $new['total_price'] +=$value['number']*$detail[$value['id']]['product_price'];
            $new['total_number'] +=$value['number'];
            $newDetail[] = [
                'product_id'=>$detail[$value['id']]['product_id'],
                'product_cover_img'=>$detail[$value['id']]['product_cover_img'],
                'product_name'=>$detail[$value['id']]['product_name'],
                'product_sku'=>$detail[$value['id']]['product_sku'],
                'product_price'=>$detail[$value['id']]['product_price'],
                'number'=>$value['number'],
                'total_money' =>$value['number']*$detail[$value['id']]['product_price'],
                'uid'     =>$detail[$value['id']]['uid'],
                'create_time'=>time()
            ];
        }
        Db::startTrans();
        $return_id = (new ProductOrderReturn())->dataUpdate($new);
        if(!$return_id){
            Db::rollback();
            throw new FailedException(['msg'=>'申请退款总订单失败']);
        }
        foreach ($newDetail as &$value){
            $value['order_return_id'] = $return_id;
        }
        $res  = (new ProductOrderDetailReturn())->saveAll($newDetail);
        if(!$res){
            Db::rollback();
            throw  new FailedException(['msg'=>'添加小订单失败']);
        }
        $where = [
            ['id','eq',$post['id']], //订单id
        ];
        $res =  (new \app\api\model\ProductOrder())->where($where)->setField("return_status",2);
        if(!$res){
            Db::rollback();
            throw  new FailedException(['msg'=>'操作失败']);
        }
        Db::commit();
        return writeJson(200);
    }

    /**
     * 用户申请退货列表
     * @param Request $request
     * @return \think\response\Json
     * @throws FailedException
     * @throws ParameterException
     */
    public function userReturnOrderList(Request $request){
        (new PageMustValidate())->goCheck();
         $post = $request->post();
         $where = [];
         $where[] = ['user_id','eq',$post['user_id']];
         $where['page'] = $post['page'];
         $dataList = (new ProductOrderReturn())->wechatListTotalWith("orderDetail",$where,"*","id desc",$post['page_number']);
         foreach ($dataList['data'] as &$value){
             if(isset($value['order_detail'])){
                 $value['type'] = (new Shop())->findOne([['id','eq',$value['order_detail'][0]['uid']]],"type");
                 $value['pick_address'] = (new Shop())->findOne([['id','eq',$value['order_detail'][0]['uid']]],"pick_address");
             }
         }
         return writeJson(200,$dataList);

    }

    /**
     * 用户退货单发货确认
     * @param Request $request
     * @return \think\response\Json
     * @throws FailedException
     * @throws ParameterException
     */
    public function userReturnOrderSure(Request $request){
        (new IdMustPositive())->goCheck();
        (new ExpressValidate())->goCheck();
        $post = $request->post();
        $where = [
            ['id','eq',$post['id']],
            ['status','eq',1]
        ];
        $count = (new ProductOrderReturn())->getCount($where);
        if($count==0){
            throw new FailedException(['msg'=>'订单不能确认发货']);
        }
        $new = [
          'id'=>$post['id'],
          'status'=>2,
          'express_name'=>$post['express_name'],
          'express_number'=>$post['express_number']
        ];
        $res = (new ProductOrderReturn())->dataUpdate($new);
        if(!$res){
            throw new FailedException(['msg'=>'操作失败']);
        }
        return writeJson(200);


    }

    /**
     * 用户退货单详情
     * @param Request $request
     * @return \think\response\Json
     * @throws FailedException
     * @throws ParameterException
     */
    public function userReturnOrderDetail(Request $request){
        (new IdMustPositive())->goCheck();
        $post = $request->post();
        $where = [
            ['id','eq',$post['id']]
        ];
        $detail = (new ProductOrderReturn())->findOneWith("order_detail",$where,"*");
        if(isset($detail['order_detail'])){
            $detail['type'] = (new Shop())->findOne([['id','eq',$detail['order_detail'][0]['uid']]],"type");
            $detail['pick_address'] = (new Shop())->findOne([['id','eq',$detail['order_detail'][0]['uid']]],"pick_address");
        }
        if(!$detail){
            throw  new NotFoundException(['msg'=>'订单不存在']);
        }
        return writeJson(200,['detail'=>$detail]);
    }

    /**
     * 用户订单详情
     * @param Request $request
     * @return \think\response\Json
     * @throws FailedException
     * @throws ParameterException
     */
    public function userOrderDetail(Request $request){
        (new IdMustPositive())->goCheck();
        $post = $request->post();
        $where = [
          ['id','eq',$post['id']]
        ];
        $detail = (new \app\api\model\ProductOrder())->findOneWith("order_detail,shop_type",$where,"*");
        if(!$detail){
            throw  new NotFoundException(['msg'=>'订单不存在']);
        }
        if(!isset($detail["shop_address"]) || $detail["shop_address"] == null){
            //查询交易大厅地址并赋值
            $config_model = (new \app\admin\controller\config\Config())->getToTheAddress(1);
            $detail['shop_address'] = $config_model['address'];
        }

        $detail["goods_money"] = 0;
        foreach ($detail['order_detail'] as &$value){
            $detail["goods_money"] += $value['total_money'];
            $value['total_money'] = (string) $value['total_money'];
        }
        $detail["goods_money"] = (string) $detail["goods_money"];

        $detail['can_return'] = 1;
        if($detail['sure_time']+7*86400>time()){
            $detail['can_return']= 2;
        }
        if(!empty($detail['send_time'])){
            $detail['send_time'] = date("Y-m-d H:i",$detail['send_time']);
        }
        if(!empty($detail['sure_time'])){
            $detail['sure_time'] = date("Y-m-d H:i",$detail['sure_time']);
        }

        //兼容赋值
        if($detail["order_type"] == null || $detail["order_type"] == ""){
            $detail["order_type"] = 1;//兼容赋值
        }

        //拼团订单
        if($detail["order_type"] == 3){
            //将团的情况查出来
            $detail["orderSpell"] = (new ProductOrderSpell())->getOrderSpell($detail["id"]);
        }
        return writeJson(200,['detail'=>$detail]);
    }
}